package com.hfuu.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hfuu.dao.read.custom.TbActivityReadDao;
import com.hfuu.dao.read.custom.TbActivityUserReadDao;
import com.hfuu.dao.read.custom.TbSubjectReadDao;
import com.hfuu.dao.read.custom.TbUserReadDao;
import com.hfuu.dao.write.custom.TbActivityUserWriteDao;
import com.hfuu.dao.write.custom.TbActivityWriteDao;
import com.hfuu.dao.write.custom.TbCheckRecordWriteDao;
import com.hfuu.enums.system.ExceptionEnum;
import com.hfuu.exceptions.ServiceExceptionSpec;
import com.hfuu.model.po.*;
import com.hfuu.service.activity.ActivityService;
import com.hfuu.service.activity.request.ActivityRequest;
import com.hfuu.service.activity.request.PayRequest;
import com.hfuu.service.activity.request.PublishActivityRequest;
import com.hfuu.service.activity.response.*;
import com.hfuu.utils.MailUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 活动类
 */
@Service
public class ActivityServiceImpl implements ActivityService {

    private static Logger logger = LoggerFactory.getLogger(ActivityServiceImpl.class);

    @Autowired
    private TbActivityReadDao tbActivityReadDao;

    @Autowired
    private TbActivityWriteDao tbActivityWriteDao;

    @Autowired
    private TbActivityUserReadDao tbActivityUserReadDao;

    @Autowired
    private TbSubjectReadDao tbSubjectReadDao;

    @Autowired
    private TbActivityUserWriteDao tbActivityUserWriteDao;

    @Autowired
    private TbUserReadDao tbUserReadDao;

    @Autowired
    private TbCheckRecordWriteDao tbCheckRecordWriteDao;

    @Override
    public PageInfo listActivity(ActivityRequest request)
            throws ServiceExceptionSpec {

//        if (request.getType() == null) {
//            throw new ServiceExceptionSpec(ExceptionEnum.USER_BASE_PARAMS_ILLEGAL);
//        }

        PageHelper.startPage(request.getPageNo(), request.getPageSize());

        List<ActivityResponse> lists = tbActivityReadDao.listActivity(request.getSubject(), request.getActivityTitle(),
                request.getStatus(), request.getType(), request.getId(), request.getUserId());

        //活动管理判断是否已参加活动
        if (request.getUserId() == null) {
            lists.stream().forEach(elem -> {
                if (request.getAttendUserId() != null) {
                    Integer count = tbActivityReadDao.countAttend
                            (elem.getId(), request.getAttendUserId());
                    if (count > 0) {
                        elem.setAttend(true);
                    } else {
                        elem.setAttend(false);
                    }
                    Integer orginzerCount = tbActivityReadDao.
                            countOrgainzer(elem.getId(), request.getAttendUserId());
                    if (orginzerCount > 0) {
                        elem.setIsOrganizer(true);
                    } else {
                        elem.setIsOrganizer(false);
                    }
                }
                if (elem.getStatus() != null && !elem.getStatus().equals(1)) {
                    elem.setAttend(true);
                }
            });
        }
        PageInfo pageInfo = new PageInfo(lists);
        return pageInfo;
    }

    @Override
    public List<ActivitySubjectResponse> listActivitySubject(ActivityRequest request) {

        List<ActivitySubjectResponse> rList = new ArrayList<>();
        TbSubjectExample example = new TbSubjectExample();
        TbSubjectExample.Criteria criteria = example.createCriteria();
        criteria.andDisabledEqualTo(0);
        List<TbSubject> lists = tbSubjectReadDao.selectByExample(example);
        if (CollectionUtils.isEmpty(lists)) {
            return null;
        }
        for (TbSubject list : lists) {
            ActivitySubjectResponse response = new ActivitySubjectResponse();
            response.setId(list.getId());
            response.setTitle(list.getTitle());
            rList.add(response);
        }
        return rList;
    }

    @Override
    public Integer insertOrUpdateActivity(PublishActivityRequest request) throws ServiceExceptionSpec {

        if (request.getType() == null) {
            throw new ServiceExceptionSpec(ExceptionEnum.USER_BASE_PARAMS_ILLEGAL);
        }

        TbActivity tbActivity = getTbActivity(request);

        if (request.getId() == null || request.getId().equals(0)) {
            //如果是募捐活动，先为无效
            if (request.getType().equals(3)) {
                tbActivity.setDisabled(1);
                //插入审核记录
                TbCheckRecord tbCheckRecord = new TbCheckRecord();
                tbCheckRecord.setUserId(request.getOrganizer());
                tbCheckRecord.setType(2);
                tbCheckRecord.setFinish(1);
                tbCheckRecordWriteDao.insertSelective(tbCheckRecord);
            }
           return tbActivityWriteDao.insertSelective(tbActivity);
        } else {
            if (request.getType().equals(3)) {
                //插入募捐后续审核记录
                TbCheckRecord tbCheckRecord = new TbCheckRecord();
                tbCheckRecord.setUserId(request.getOrganizer());
                tbCheckRecord.setType(3);
                tbCheckRecord.setFinish(1);
                tbCheckRecordWriteDao.insertSelective(tbCheckRecord);
            }
        }
        return tbActivityWriteDao.updateByPrimaryKeySelective(tbActivity);
    }

    @Override
    public Integer deleteActivityById(ActivityRequest request) throws ServiceExceptionSpec {

        if (request.getId() == null) {
            throw new ServiceExceptionSpec(ExceptionEnum.USER_BASE_PARAMS_ILLEGAL);
        }
        TbActivity tbActivity = new TbActivity();
        tbActivity.setDisabled(1);
        tbActivity.setId(request.getId());
       return tbActivityWriteDao.updateByPrimaryKeySelective(tbActivity);
    }

    /**
     * 通过活动id,获得用户评价
     * @param request
     * @return
     */
    @Override
    public List<ActivityDetailResponse> listActivityDetail(ActivityRequest request) throws ServiceExceptionSpec {

        if (request.getId() == null) {
            throw new ServiceExceptionSpec(ExceptionEnum.USER_BASE_PARAMS_ILLEGAL);
        }
        return tbActivityReadDao.listActivityDetail(request.getId());
    }

    /**
     * 更新活动评价
     * @param request
     * @return
     */
    @Override
    public Integer updateActivityDetail(ActivityRequest request) throws ServiceExceptionSpec {

        if (request.getId() == null) {
            throw new ServiceExceptionSpec(ExceptionEnum.USER_BASE_PARAMS_ILLEGAL);
        }
        TbActivityUser tbActivityUser = new TbActivityUser();
        tbActivityUser.setId(request.getId());
        tbActivityUser.setRemark(request.getRemark());
        tbActivityUser.setOrganizerScore(request.getOrganizerScore());
        tbActivityUser.setUserScore(request.getUserScore());

        return tbActivityUserWriteDao.updateByPrimaryKeySelective(tbActivityUser);
    }

    /**
     * 用户参加报名活动
     * @param request
     * @return
     */
    @Override
    public Boolean attendActivity(ActivityRequest request) throws ServiceExceptionSpec {

        if (request.getId() == null || request.getUserId() == null
                || request.getActivityStartTime() == null) {
            throw new ServiceExceptionSpec(ExceptionEnum.USER_BASE_PARAMS_ILLEGAL);
        }
        //如果时间为活动前一小时，则不准参加
        if (request.getActivityStartTime() != null
        && request.getActivityStartTime() - (new Date()).getTime() < 60*60*1000) {
            throw new ServiceExceptionSpec(ExceptionEnum.USER_NOT_ATTENT_TIME);
        }

        //先判断已报名人数
        TbActivity tbActivity = tbActivityReadDao.selectByPrimaryKey(request.getId());
        if (tbActivity == null) {
            throw new ServiceExceptionSpec(ExceptionEnum.NOT_FIND_ACTIVITY);
        }

        Integer personCount = tbActivity.getPersionCount() == null ? 0 : tbActivity.getPersionCount();
        Integer requireCount = tbActivity.getRequireCount() == null ? 0 : tbActivity.getRequireCount();
        //报名人数未达到上限
        if (personCount < requireCount) {
            TbActivityUser tbActivityUser = new TbActivityUser();
            tbActivityUser.setDisabled(0);
            tbActivityUser.setUserId(request.getUserId());
            tbActivityUser.setActivityId(request.getId());
            tbActivityUserWriteDao.insertSelective(tbActivityUser);

            //报名人数加一
            tbActivity.setPersionCount(tbActivity.getPersionCount() + 1);
            tbActivityWriteDao.updateByPrimaryKeySelective(tbActivity);
            return true;
        }
        //处理报名人数达到上线的情况：判断报名人的星级(参加活动时间)是否大于已经有的报名人
        List<AttendActivityResponse> lists = tbActivityReadDao.attendActivityTime(request.getId());
        if (CollectionUtils.isEmpty(lists)) {
            return false;
        }
        TbUser tbUser = tbUserReadDao.selectByPrimaryKey(request.getUserId());
        //活动时间大于当前用户,删除当前用户报名资格，报名该用户
        if (tbUser.getVolunteerTime() != null &&
                tbUser.getVolunteerTime().compareTo(lists.get(0).getMinTime()) > 0) {
            TbActivityUser tbActivityUser = new TbActivityUser();
            TbActivityUserExample example = new TbActivityUserExample();
            TbActivityUserExample.Criteria criteria = example.createCriteria();
            criteria.andDisabledEqualTo(0).andUserIdEqualTo(lists.get(0).getUserId())
                    .andActivityIdEqualTo(request.getId());
            tbActivityUser.setDisabled(1);
            tbActivityUserWriteDao.updateByExampleSelective(tbActivityUser, example);

            //先获得用户邮箱
            TbUser tbUser1 = tbUserReadDao.selectByPrimaryKey(lists.get(0).getUserId());
            //邮件通知用户被取消参加资格
            MailUtil.singleMail(tbUser1.getEmail(),request.getActivityTitle() +
                    ", 活动不能参加！","抱歉，经审核您不具有参加" + request.getActivityTitle() + "活动的资格。");

            //参加活动
            TbActivityUser tbActivityUser1 = new TbActivityUser();
            tbActivityUser1.setDisabled(0);
            tbActivityUser1.setUserId(request.getUserId());
            tbActivityUser1.setActivityId(request.getId());
            tbActivityUserWriteDao.insertSelective(tbActivityUser1);

            //邮件提示用户
            MailUtil.singleMail(tbUser.getEmail(),request.getActivityTitle() +
                    ", 等待审核参加！","尊敬的志愿者先生，你参加的" + request.getActivityTitle() + "活动正在审核中，若活动之前未邮件提醒，则参加成功。");
            return true;
        }
        logger.info("用户报名失败");
        return false;
    }

    /**
     * 更新募捐金额
     * @param request
     * @throws ServiceExceptionSpec
     */
    @Override
    public Boolean updateFunMoney(PayRequest request) throws ServiceExceptionSpec {

        if (StringUtils.isEmpty(request.getUserActivityId()) || request.getPayMoney() == null) {
            throw new ServiceExceptionSpec(ExceptionEnum.USER_BASE_PARAMS_ILLEGAL);
        }
        String[] strs = request.getUserActivityId().split("_");
        if (strs == null || strs.length != 2) {
            return false;
        }
        TbActivityUserExample example = new TbActivityUserExample();
        TbActivityUserExample.Criteria criteria = example.createCriteria();
        criteria.andDisabledEqualTo(0).andActivityIdEqualTo(Integer.parseInt(strs[0]))
                .andUserIdEqualTo(Integer.parseInt(strs[1]));
        List<TbActivityUser> lists = tbActivityUserReadDao.selectByExample(example);
        if (CollectionUtils.isEmpty(lists)) {
            return false;
        }
        TbActivityUser tbActivityUser = lists.get(0);
        tbActivityUser.setPersonFundMoney(tbActivityUser.getPersonFundMoney() == null ? request.getPayMoney()
                : request.getPayMoney().add(tbActivityUser.getPersonFundMoney()));
        tbActivityUserWriteDao.updateByPrimaryKeySelective(tbActivityUser);

        //更新活动总金额
        Integer activityId = tbActivityUser.getActivityId();
        TbActivity tbActivity = tbActivityReadDao.selectByPrimaryKey(activityId);
        BigDecimal totalMoney = new BigDecimal(tbActivity.getFundraisingMoney() == null ? "0" : tbActivity.getFundraisingMoney());
        tbActivity.setFundraisingMoney(totalMoney.add(request.getPayMoney()).toString());
        tbActivityWriteDao.updateByPrimaryKeySelective(tbActivity);
        return true;
    }

    /**
     * 募捐插入用户活动表
     * @param request
     * @return
     * @throws ServiceExceptionSpec
     */
    @Override
    public Boolean attendFunActivity(ActivityRequest request) throws ServiceExceptionSpec {
        if (request.getId() == null || request.getUserId() == null) {
            throw new ServiceExceptionSpec(ExceptionEnum.USER_BASE_PARAMS_ILLEGAL);
        }
        TbActivityUser tbActivityUser = new TbActivityUser();
        tbActivityUser.setDisabled(0);
        tbActivityUser.setUserId(request.getUserId());
        tbActivityUser.setActivityId(request.getId());
        tbActivityUserWriteDao.insertSelective(tbActivityUser);

        return true;
    }

    @Override
    public List<PersonFunResponse> getPersonFun(PayRequest request) throws ServiceExceptionSpec {

        if (request.getUserId() == null) {
            throw new ServiceExceptionSpec(ExceptionEnum.USER_BASE_PARAMS_ILLEGAL);
        }
        return tbActivityReadDao.getPersonFun(request.getUserId());
    }

    private TbActivity getTbActivity (PublishActivityRequest request) {
        TbActivity tbActivity = new TbActivity();
        tbActivity.setId(request.getId());
        tbActivity.setAttendanceCount(String.valueOf(request.getAttendanceCount()));
        tbActivity.setContent(request.getContent());
        tbActivity.setPersionCount(request.getPersionCount());
        tbActivity.setOrganizer(request.getOrganizer());
        tbActivity.setRequireCount(request.getRequireCount());
        tbActivity.setRequired(request.getRequire());
        tbActivity.setSubject(request.getSubject());
        tbActivity.setStatus(1);
        tbActivity.setTitle(request.getActivityTitle());
        tbActivity.setType(request.getType());

        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            if (!StringUtils.isEmpty(request.getStartTime())) {
                tbActivity.setStartTime(sf.parse(request.getStartTime()));
            }
            if (!StringUtils.isEmpty(request.getEndTime())) {
                tbActivity.setEndTime(sf.parse(request.getEndTime()));
            }
        } catch (Exception e) {
            e.getStackTrace();
        }
        return tbActivity;
    }
}
